namespace SoundFingerprinting
{
    using System.Collections.Generic;
    using SoundFingerprinting.Command;
    using SoundFingerprinting.Data;

    /// <summary>
    ///  Model service interface providing access to various hashes storages.
    /// </summary>
    /// <remarks>
    ///   Details about available hashes storage can be found <a href="https://github.com/AddictedCS/soundfingerprinting/wiki/Other-Storages">here</a>.
    /// </remarks>
    public interface IModelService : IQueryService
    {
        /// <summary>
        ///  Gets details about underlying storage (i.e. track count, hashes count etc.)
        /// </summary>
        IEnumerable<ModelServiceInfo> Info { get; }

        /// <summary>
        ///  Inserts new track with associated hashes into the storage.
        /// </summary>
        /// <param name="trackInfo">Track related information.</param>
        /// <param name="hashes">Instance of <see cref="AVHashes"/> generated by <see cref="FingerprintCommand"/>.</param>
        /// <remarks>
        ///  Inserting track with the same <see cref="TrackInfo.Id"/> will overwrite existing hashes to provided <paramref name="hashes"/>.
        /// </remarks>
        void Insert(TrackInfo trackInfo, AVHashes hashes);

        /// <summary>
        ///  Updates track info <see cref="TrackInfo.Id"/> is used as the key to the object to update.
        ///  Fields that will be updated: <see cref="TrackInfo.Title"/>, <see cref="TrackInfo.Artist"/>, <see cref="TrackInfo.MetaFields"/>.
        /// </summary>
        /// <param name="trackInfo">Track to update.</param>
        void UpdateTrack(TrackInfo trackInfo);
        
        /// <summary>
        ///  Removes a track and associated hashes from the storage by track ID.
        /// </summary>
        /// <param name="trackId">Track ID to remove.</param>
        void DeleteTrack(string trackId);

        /// <summary>
        ///  Gets hashes for a particular track.
        /// </summary>
        /// <param name="trackId">Track identifier.</param>
        /// <returns>List of hashes corresponding to track by ID.</returns>
        AVHashes ReadHashesByTrackId(string trackId);

        /// <summary>
        ///  Read track by ID.
        /// </summary>
        /// <param name="trackId">Track ID to read the track</param>
        /// <returns>TrackInfo if storage contains a track with provided ID, null otherwise</returns>
        TrackInfo? ReadTrackById(string trackId);
        
        /// <summary>
        ///  Read all track ids from the storage
        /// </summary>
        /// <returns>List of all inserted track ids</returns>
        IEnumerable<string> GetTrackIds();
    }
}
